package com.llw.notify.notification;

import android.app.Notification;
import android.os.Bundle;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.llw.notify.util.HTMLMarker;

import java.util.LinkedList;

/**
 * 从一个 Notification 中抽取 通知的文本内容
 */
public class NotificationExtractor {
    private final static String TAG = NotificationExtractor.class.getSimpleName();

    public enum Content {
        TITLE("标题", Notification.EXTRA_TITLE),
        TEXT("内容", Notification.EXTRA_TEXT),
        TITLE_BIG("大文本标题", Notification.EXTRA_TITLE_BIG),
        BIG_TEXT("大文本内容", Notification.EXTRA_BIG_TEXT),
        SUB_TEXT("子文本", Notification.EXTRA_SUB_TEXT),
        SUMMARY_TEXT("总结文本", Notification.EXTRA_SUMMARY_TEXT),
        INFO_TEXT("信息文本", Notification.EXTRA_INFO_TEXT),
        ;

        public final String description;
        public final String key;

        Content(final String description, final String key) {
            this.description = description;
            this.key = key;
        }

        boolean equalsAnyOf(Content... contents) {
            for (Content content : contents) {
                if (this == content) {
                    return true;
                }
            }
            return false;
        }
    }

    public static String extractKey(@NonNull final Notification notification,
                                    @NonNull final Content content) {
        return notification.extras.getString(content.key);
    }

    /**
     * 构造一个通知内容的组成部门，将类型描述加粗
     *
     * @param description 类型
     * @param delimiter 调用者相关，请参考 {@link #extract(Notification, String)}
     * @param content 与 description 对应的内容
     * @return 构造好的内容字符串
     */
    private static String contentJoin(final String description, final String delimiter, final String content) {
        return HTMLMarker.boldRaw(description) + delimiter + content;
    }

    /**
     * 提取不加修饰的通知内容，将不同的通知域使用 \n 连接起来，便于对通知内容进行检查
     *
     * @param notification 通知
     * @return 使用 \n 连接起来的不同通知域的内容
     */
    public static String extractRaw(@NonNull final Notification notification) {
        final StringBuilder rawContent = new StringBuilder();
        final Bundle extras = notification.extras;
        String temp = null;
        for (Content content : Content.values()) {
            temp = extras.getString(content.key);
            if (TextUtils.isEmpty(temp) == true) {
                continue;
            }
            rawContent.append(temp).append("\n");
        }
        return rawContent.toString();
    }

    /**
     * 抽取 Notification 中的数据，并使用使用 delimiter 连接 key 与 对应的内容
     *
     * @param notification 通知
     * @param delimiter 分隔符
     * @return 构造出的通知内容
     */
    public static LinkedList<String> extract(@NonNull final Notification notification,
                                             @NonNull final String delimiter) {
        final LinkedList<String> result = new LinkedList<>();
        final Bundle notificationExtras = notification.extras;
        String temp = null;
        for (Content content : Content.values()) {
            // 略过通知标题、通知内容、通知大文本内容的处理
            if (content.equalsAnyOf(Content.TITLE, Content.TEXT, Content.BIG_TEXT)) {
                continue;
            }
            temp = notificationExtras.getString(content.key);
            if (TextUtils.isEmpty(temp) == false) {
                result.add(contentJoin(content.description, delimiter, temp));
            }
        }

        // 单独处理通知内容
        contentZipper(result, notificationExtras, delimiter);

        return result;
    }

    /**
     * 对通知内容进行压缩，也就是在 通知内容与通知大文本内容 一致时，
     * 将大文本域标记为 “同内容”
     *
     * @param result 调用者相关，请参考 {@link #extract(Notification, String)}
     * @param notificationExtras 通知内容
     * @param delimiter 调用者相关，请参考 {@link #extract(Notification, String)}
     */
    private static void contentZipper(final LinkedList<String> result,
                                      final Bundle notificationExtras,
                                      final String delimiter) {
        final String text = notificationExtras.getString(Content.TEXT.key);
        final String bigText = notificationExtras.getString(Content.BIG_TEXT.key);

        // 按需添加大文本内容
        if (TextUtils.isEmpty(bigText) == false) {
            if (TextUtils.isEmpty(text) == false && bigText.equals(text)) {
                result.addFirst(contentJoin(Content.BIG_TEXT.description, delimiter, "同内容"));
            }
            else {
                result.addFirst(contentJoin(Content.BIG_TEXT.description, delimiter, bigText));
            }
        }
        // 按需添加通知内容
        if (TextUtils.isEmpty(text) == false) {
            result.addFirst(contentJoin(Content.TEXT.description, delimiter, text));
        }
        return;
    }

    /**
     * 使用中文冒号 ”：“ 调用 {@link #extract(Notification, String)}
     */
    public static LinkedList<String> extract(@NonNull final Notification notification) {
        return NotificationExtractor.extract(notification, "：");
    }
}
